﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using Interscape.TwilioClient.Components;
using Interscape.TwilioClient.ServiceHelpers;
using Microsoft.Http;

namespace Interscape.TwilioClient
{

    #region Service Interface

    [ServiceContract]
    public interface IOutgoingCallerIdManager
    {
        [OperationContract]
        [TwilioWcfSerializer]
        [WebGet(
            BodyStyle = WebMessageBodyStyle.WrappedResponse,
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = "/Accounts/{accountSid}/OutgoingCallerIds"
            )]
        OutgoingCallerIdList GetAll(string accountSid);

        [OperationContract]
        [TwilioWcfSerializer]
        [WebGet(
            BodyStyle = WebMessageBodyStyle.WrappedResponse,
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = "/Accounts/{accountSid}/OutgoingCallerIds/{callerIdSid}"
            )]
        OutgoingCallerId Get(string accountSid, string callerIdSid);

    }

    #endregion

    /// <summary>
    /// 
    /// </summary>
    public class OutgoingCallerIdManager : ManagerBase<IOutgoingCallerIdManager>, IOutgoingCallerIdManager
    {

        #region Constructors

        /// <summary>
        /// Creates a new instance of the OutgoingCallerIdManager.
        /// </summary>
        /// <param name="accountSid">The 34 character string that uniquely identifies the Account which will be used to make the TwilioAPI requests.</param>
        /// <param name="authToken">The "password" for your Twilio API calls.</param>
        public OutgoingCallerIdManager(string accountSid, string authToken) : base(accountSid, authToken)
        {
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public OutgoingCallerIdList GetAll()
        {
            return this.GetAll(this.AccountSid);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="accountSid">A 34 character string that uniquely identifies the Account associated with this resource.</param>
        /// <returns></returns>
        public OutgoingCallerIdList GetAll(string accountSid)
        {
            return this.Channel.GetAll(accountSid);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="callerIdSid"></param>
        /// <returns></returns>
        public OutgoingCallerId Get(string callerIdSid)
        {
            return this.Get(this.AccountSid, callerIdSid);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="accountSid">A 34 character string that uniquely identifies the Account associated with this resource.</param>
        /// <param name="callerIdSid"></param>
        /// <returns></returns>
        public OutgoingCallerId Get(string accountSid, string callerIdSid)
        {
            return this.Channel.Get(accountSid, callerIdSid);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="outgoingCallerId"></param>
        /// <returns></returns>
        /// <remarks>
        /// You can pass an additional parameter to this method, CallDelay, through the OutgoingCallerId.PostArguments.
        /// This represents the number of seconds, between 0 and 60, to wait before initiating the Validation Call. Defaults to 0.
        /// </remarks>
        public OutgoingCallerId Add(OutgoingCallerId outgoingCallerId)
        {
            System.Net.ServicePointManager.Expect100Continue = false;
            HttpUrlEncodedForm form = new HttpUrlEncodedForm();

            if (string.IsNullOrEmpty(outgoingCallerId.PhoneNumber)) throw new ArgumentNullException("The PhoneNumber for adding an OutgoingCallerId is required.");
            form.Add("PhoneNumber", outgoingCallerId.PhoneNumber);
            if (!string.IsNullOrEmpty(outgoingCallerId.FriendlyName)) form.Add("FriendlyName", outgoingCallerId.FriendlyName);
            foreach (KeyValuePair<string, string> arg in outgoingCallerId.PostArguments)
            {
                form.Add(arg.Key, arg.Value);
            }

            return ProcessResponse(this.HttpClientHelper.Post(this.Urls.OutgoingCallerIdsUrl(true), form.CreateHttpContent()));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="outgoingCallerId"></param>
        /// <returns></returns>
        public OutgoingCallerId Update(OutgoingCallerId outgoingCallerId)
        {
            System.Net.ServicePointManager.Expect100Continue = false;
            HttpUrlEncodedForm form = new HttpUrlEncodedForm();

            if (string.IsNullOrEmpty(outgoingCallerId.FriendlyName)) throw new ArgumentNullException("The FriendlyName for updating an OutgoingCallerId is required.");
            form.Add("FriendlyName", outgoingCallerId.FriendlyName);
            //This is included for compatibility with future iterations of the Twilio API
            foreach (KeyValuePair<string, string> arg in outgoingCallerId.PostArguments)
            {
                form.Add(arg.Key, arg.Value);
            }

            return ProcessResponse(this.HttpClientHelper.Post(this.Urls.OutgoingCallerIdInstanceUrl(true, outgoingCallerId.Sid), form.CreateHttpContent()));
        }

        #region Private Helper Methods

        /// <summary>
        /// 
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private OutgoingCallerId ProcessResponse(HttpResponseMessage response)
        {
            return (OutgoingCallerId)ServiceUtility.ProcessHttpResponseMessage(response, typeof(OutgoingCallerId));
        }

        #endregion




    }
}
